#include "sys/socket.h"
#include "netinet/in.h"
#include "stdio.h"
#include "errno.h"
#include "time.h"
#include "string.h"
#include "stdlib.h"

#include "tcp_funs.h"

#define BUFSIZE 5000

void process_msg_from_file(int conn_fd);
void process_msg_from_stdin(int conn_fd);
void process_specificated_msg_from_file(int conn_fd);

void tcp_client()
{
	int conn_fd;
	struct sockaddr_in sockaddr_remote;
	int connect_ret_val, send_ret_val, recv_ret_val;
	char buf[BUFSIZE];
	int is_server_shutdown = 0;

	conn_fd = socket(PF_INET, SOCK_STREAM, 0);
	if(-1 == conn_fd) {
		printf("&tcp_client: fail to create socket, program exit.\n");
		printf("&tcp_client: The failure reason is %d.\n", errno);
		exit(0);
	}

	memset(&sockaddr_remote, 0, sizeof(sockaddr_remote));
	sockaddr_remote.sin_family = AF_INET;
	sockaddr_remote.sin_port = htons(8000);
	sockaddr_remote.sin_addr.s_addr = inet_addr("127.0.0.1");

	connect_ret_val = connect(conn_fd, (struct sockaddr*)&sockaddr_remote,
			sizeof(struct sockaddr));
	if(-1 == connect_ret_val) {
		printf("&tcp_client: fail to connect server, program exit.\n");
		printf("&tcp_client: The failure reason is %d.\n", errno);
		exit(0);
	}

	process_msg_from_file(conn_fd);

	close(conn_fd);

	return;
}

void process_msg_from_stdin(int conn_fd)
{
	int send_ret_val, recv_ret_val;
	char buf[BUFSIZE];
	int is_server_shutdown = 0;

	// receive welcome message from server
	memset(buf, 0, BUFSIZE);
	recv_ret_val = recv(conn_fd, buf, BUFSIZE, 0);
	if(-1 == recv_ret_val) {
		printf("&tcp_client: fail to receive message from server, program exit.\n");
		printf("&tcp_client: The failure reason is %d.\n", errno);
		exit(0);
	}
	else if(0 == recv_ret_val) {
		printf("&tcp_client: server close the connection.\n");
		is_server_shutdown = 1;
	}
	else {
		buf[recv_ret_val] = '\0';
		printf("&tcp_client: Data received from server is: %s\n", buf);
	}

	while(0 == is_server_shutdown) {
		memset(buf, 0, BUFSIZE);

		// enter a string from standard input
		printf("plz enter a string to send to server:\n");
		if(NULL != fgets(buf, 50, stdin)) {
			printf("The length of input string is %d\n", strlen(buf));
			if(0 == strcmp(buf, "quit\n")) {
				break;
			}

			// send data to server
			send_ret_val = send(conn_fd, buf, strlen(buf), 0);
			if(-1 == send_ret_val) {
				printf("&tcp_client: fail to send message to client, program exit.\n");
				printf("&tcp_client: The failure reason is %d.\n", errno);
				exit(0);
			}

			// receive data from server
			recv_ret_val = recv(conn_fd, buf, BUFSIZE, 0);
			if(-1 == recv_ret_val) {
				printf("&tcp_client: fail to receive message from server, program exit.\n");
				printf("&tcp_client: The failure reason is %d.\n", errno);
				exit(0);
			}
			else if(0 == recv_ret_val) {
				printf("&tcp_client: server shutdown the connection.\n");
				is_server_shutdown = 1;
			}
			else {
				buf[recv_ret_val] = '\0';
				printf("&tcp_client: Data received from server is: %s\n", buf);
			}
		}
		else {
			printf("&tcp_client: the input string is NULL,"
					" continue to get the string from stdin.\n");
		}
	} //while

	return;
}

void process_specificated_msg_from_file(int conn_fd)
{
	struct employee_t employee;
	int send_ret_val, recv_ret_val;
	char buf[BUFSIZE];
	int info_count;
	int is_server_shutdown = 0;
	FILE* pFile = NULL;

	// receive a welcome message from server
	memset(buf, 0, BUFSIZE);
	recv_ret_val = recv(conn_fd, buf, BUFSIZE, 0);
	if(-1 == recv_ret_val) {
		printf("&tcp_client: fail to receive message from server, program exit.\n");
		printf("&tcp_client: The failure reason is %d.\n", errno);
		exit(0);
	}
	else if(0 == recv_ret_val) {
		printf("&tcp_client: server close the connection.\n");
		is_server_shutdown = 1;
	}
	else {
		buf[recv_ret_val] = '\0';
		printf("&tcp_client: Data received from server is: %s\n", buf);
	}

	pFile = fopen("TestProject/Test_data/tcp_client.input", "r");
	if(NULL == pFile) {
		printf("&tcp_client: fail to open file, program exit.\n");
		exit(0);
	}

	while(0 == is_server_shutdown) {
		printf("&tcp_client: get data from file.\n");

		info_count = 0;

		memset(buf, 0, BUFSIZE);
		if(NULL != fgets(buf, BUFSIZE, pFile)) {
			buf[strlen(buf) - 1] = 0;
			strcpy(employee.name, buf);
			info_count ++;
		}
		memset(buf, 0, BUFSIZE);
		if(NULL != fgets(buf, BUFSIZE, pFile)) {
			employee.age = atoi(buf);
			info_count ++;
		}
		memset(buf, 0, BUFSIZE);
		if(NULL != fgets(buf, BUFSIZE, pFile)) {
			employee.gender = atoi(buf);
			info_count ++;
		}
		memset(buf, 0, BUFSIZE);
		if(NULL != fgets(buf, BUFSIZE, pFile)) {
			buf[strlen(buf) - 1] = 0;
			employee.employed_year = atof(buf);
			info_count ++;
		}
		memset(buf, 0, BUFSIZE);
		if(NULL != fgets(buf, BUFSIZE, pFile)) {
			buf[strlen(buf) - 1] = 0;
			employee.salary = atof(buf);
			info_count ++;
		}

		if(5 == info_count) {
			printf("The length of input message is %d\n", sizeof(employee));

			// send data to server
			send_ret_val = send(conn_fd, (void*)&employee, sizeof(employee), 0);
			if(-1 == send_ret_val) {
				printf("&tcp_client: fail to send message to client, program exit.\n");
				printf("&tcp_client: The failure reason is %d.\n", errno);
				exit(0);
			}
		}
		else {
#ifdef DEBUG_TCP
			printf("&tcp_client: info_count is %d\n", info_count);
#endif
			printf("&tcp_client: reach end of file, close connection socket.\n");
			break;
		}
	} //while

	return;
}

void process_msg_from_file(int conn_fd)
{
	int send_ret_val, recv_ret_val;
	char buf[BUFSIZE];
	int is_server_shutdown = 0;
	FILE* pFile = NULL;

	// receive welcome message from server
	memset(buf, 0, BUFSIZE);
	recv_ret_val = recv(conn_fd, buf, BUFSIZE, 0);
	if(-1 == recv_ret_val) {
		printf("&tcp_client: fail to receive message from server, program exit.\n");
		printf("&tcp_client: The failure reason is %d.\n", errno);
		exit(0);
	}
	else if(0 == recv_ret_val) {
		printf("&tcp_client: server close the connection.\n");
		is_server_shutdown = 1;
	}
	else {
		buf[recv_ret_val] = '\0';
		printf("&tcp_client: Data received from server is: %s\n", buf);
	}

	pFile = fopen("TestProject/Test_data/tcp_client.input", "r");
	if(NULL == pFile) {
		printf("&tcp_client: fail to open file, program exit.\n");
		exit(0);
	}

	while(0 == is_server_shutdown) {
		memset(buf, 0, BUFSIZE);

		if(NULL != fgets(buf, BUFSIZE, pFile)) {
#ifdef DEBUG_TCP
			printf("&tcp_client: the string read from file is %s\n", buf);
			printf("&tcp_client: The length of input string is %d\n", strlen(buf));
#endif

			if(0 == strcmp(buf, "quit\n")) {
				break;
			}

			// send data to server
			send_ret_val = send(conn_fd, buf, strlen(buf), 0);
			if(-1 == send_ret_val) {
				printf("&tcp_client: fail to send message to client, program exit.\n");
				printf("&tcp_client: The failure reason is %d.\n", errno);
				exit(0);
			}

			// receive data from server
			recv_ret_val = recv(conn_fd, buf, BUFSIZE, 0);
			if(-1 == recv_ret_val) {
				printf("&tcp_client: fail to receive message from server, program exit.\n");
				printf("&tcp_client: The failure reason is %d.\n", errno);
				exit(0);
			}
			else if(0 == recv_ret_val) {
				printf("&tcp_client: server shutdown the connection.\n");
				is_server_shutdown = 1;
			}
			else {
				buf[recv_ret_val] = '\0';
				printf("&tcp_client %d: Data received from server is: %s\n", (int)getpid(), buf);
			}
		}
		else {
			printf("&tcp_client: the input string is NULL,"
					" wait 2 minutes to close.\n");
			sleep(120);
			break;
		}
	} //while

	return;
}
